﻿using System;
using System.Collections.Generic;

namespace UpdaterForm.CustomTreeView
{
    public abstract class ATreeNode : Observable
    {
        #region Data

        private bool? _isChecked = false;
        private ATreeNode _parent;

        #endregion // Data

        private bool _isTransfered;
        public List<ATreeNode> Children { get; set; }
        public bool IsInitiallySelected { get; set; }

        public bool IsTransfered
        {
            get { return _isTransfered; }
            set
            {
                _isTransfered = value;
                OnPropertyChanged("IsTransfered");
            }
        }

        public String Name { get; set; }


        public int FileTransfered { get; set; }

        public ATreeNode Root
        {
            get
            {
                var tmp = this;
                while (tmp._parent != null)
                    tmp = tmp._parent;
                
                return tmp;
            }
        }

        public bool? IsChecked
        {
            get { return _isChecked; }
            set { SetIsChecked(value, true, true); }
        }

        private void SetIsChecked(bool? value, bool updateChildren, bool updateParent)
        {
            if (value == _isChecked)
                return;

            _isChecked = value;

            if (updateChildren && _isChecked.HasValue)
                Children.ForEach(c => c.SetIsChecked(_isChecked, true, false));

            if (updateParent && _parent != null)
                _parent.VerifyCheckState();

            OnPropertyChanged("IsChecked");
        }

        private void VerifyCheckState()
        {
            bool? state = null;
            for (int i = 0; i < Children.Count; ++i)
            {
                bool? current = Children[i].IsChecked;
                if (i == 0)
                {
                    state = current;
                }
                else if (state != current)
                {
                    state = null;
                    break;
                }
            }
            SetIsChecked(state, false, true);
        }

        protected void SetParent()
        {
            foreach (ATreeNode child in Children)
            {
                child._parent = this;
                child.Initialize();
            }
        }

        public abstract void Initialize();
        public abstract void Apply(bool custom);
    }
}